package com.breeze.components.redis.lock;

import com.breeze.components.core.util.spring.SpElUtil;
import com.breeze.components.redis.util.RedissonUtil;
import java.lang.reflect.Method;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @author breeze
 */
@Slf4j
@Aspect
@Component
@Order(0)
public class RedissonLockAspect {

  @Around("@annotation(com.breeze.components.redis.lock.RedissonLock)")
  public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
    Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
    RedissonLock redissonLock = method.getAnnotation(RedissonLock.class);
    Object[] args = SpElUtil.parseSpEl(method, joinPoint.getArgs(), redissonLock.key());
    return RedissonUtil.tryLockRet(
        joinPoint::proceed,
        String.format(redissonLock.prefix() + ":%s".repeat(args.length), args),
        redissonLock.time(),
        redissonLock.unit());
  }
}
